package com.guomei.service.exam.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guomei.bean.exam.domain.Exam;
import com.guomei.bean.exam.domain.ExamQuestion;
import com.guomei.bean.exam.domain.ExamQuestionExcelImport;
import com.guomei.bean.exam.domain.ExamQuestionSubjectiveExcelImport;
import com.guomei.constans.QuestionTypeCode;
import com.guomei.mapper.curse.ExamMapper;
import com.guomei.mapper.curse.ExamQuestionMapper;
import com.guomei.service.exam.ExamQuestionService;
import com.guomei.utils.PageData;
import com.guomei.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 考试题目服务实现类
 */
@Service
@Slf4j
@Transactional
public class ExamQuestionServiceImpl implements ExamQuestionService {
    @Resource
    private ExamQuestionMapper examQuestionMapper;

    @Resource
    private ExamMapper examMapper;

    @Override
    public ExamQuestion getById(Long id) {
        if (id == null) {
            return null;
        }
        return examQuestionMapper.selectById(id);
    }

    @Override
    public List<ExamQuestion> getAll() {
        return examQuestionMapper.selectAll();
    }

    @Override
    public Result<?> getByCondition(ExamQuestion examQuestion) {
        PageHelper.startPage(examQuestion.getPageNum(), examQuestion.getPageSize());
        List<ExamQuestion> examQuestions = examQuestionMapper.selectByCondition(examQuestion);
        // 封装分页结果到PageData
        PageData<ExamQuestion> pageData = new PageData<>();
        PageInfo<ExamQuestion> pageInfo = new PageInfo<>(examQuestions);
        pageData.setTotal(pageInfo.getTotal());
        pageData.setData(pageInfo.getList());
        pageData.setPageNum(examQuestion.getPageNum());
        pageData.setPageSize(examQuestion.getPageSize());
        return Result.success(pageData);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(ExamQuestion examQuestion) {
        if (examQuestion == null) {
            return false;
        }

        // 设置创建和更新时间
        LocalDateTime now = LocalDateTime.now();
        examQuestion.setCreatedTime(now);
        examQuestion.setUpdatedTime(now);

        // 设置默认值
        if (examQuestion.getSortOrder() == null) {
            examQuestion.setSortOrder(0);
        }
        if (examQuestion.getScore() == null) {
            examQuestion.setScore(0);
        }

        return examQuestionMapper.insert(examQuestion) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchSave(List<ExamQuestion> examQuestions) {
        if (examQuestions == null || examQuestions.isEmpty()) {
            return false;
        }

        LocalDateTime now = LocalDateTime.now();
        for (ExamQuestion examQuestion : examQuestions) {
            // 设置创建和更新时间
            examQuestion.setCreatedTime(now);
            examQuestion.setUpdatedTime(now);

            // 设置默认值
            if (examQuestion.getSortOrder() == null) {
                examQuestion.setSortOrder(0);
            }
            if (examQuestion.getScore() == null) {
                examQuestion.setScore(0);
            }
        }

        return examQuestionMapper.batchInsert(examQuestions) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(ExamQuestion examQuestion) {
        if (examQuestion == null || examQuestion.getId() == null) {
            return false;
        }

        // 更新时间设为当前时间
        examQuestion.setUpdatedTime(LocalDateTime.now());

        return examQuestionMapper.updateById(examQuestion) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeById(Long id) {
        if (id == null) {
            return false;
        }
        return examQuestionMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchRemove(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        return examQuestionMapper.batchDelete(ids) > 0;
    }

    @Override
    public List<ExamQuestion> getByExamId(Long examId) {
        if (examId == null) {
            return null;
        }
        return examQuestionMapper.selectByExamId(examId);
    }

    @Override
    public List<ExamQuestion> getByExamIdAndType(Long examId, Short questionType) {
        if (examId == null || questionType == null) {
            return null;
        }
        return examQuestionMapper.selectByExamIdAndType(examId, questionType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByExamId(Long examId) {
        if (examId == null) {
            return false;
        }
        Exam exam = examMapper.selectById(examId);
        if (exam == null){
            log.info("考试不存在");
            return false;
        }
        if (exam.getStatus() != 0){
            log.info("考试已发布，不能删除");
            return false;
        }
        return examQuestionMapper.deleteByExamId(examId) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> importFromExcelFile(Long examId, MultipartFile file) {
        try {
            int QuestionType = QuestionTypeCode.OBJECTIVE.getCode();
            if (examId == null) {
                return Result.fail("考试ID不能为空");
            }
            if (file == null || file.isEmpty()) {
                return Result.fail("请选择要导入的Excel文件");
            }

            // 检查文件类型
            String fileName = file.getOriginalFilename();
            if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
                return Result.fail("请上传Excel文件（.xlsx或.xls格式）");
            }

            // 配置EasyPoi导入参数
            ImportParams importParams = new ImportParams();
//            importParams.setTitleRows(1); // 标题行数
//            importParams.setHeadRows(1);  // 表头行数
//            importParams.setNeedVerify(false); // 不需要校验

            // 解析Excel文件
            List<ExamQuestionExcelImport> excelDataList;
            try (InputStream inputStream = file.getInputStream()) {
                excelDataList = ExcelImportUtil.importExcel(
                    inputStream, 
                    ExamQuestionExcelImport.class, 
                    importParams
                );
            }

            if (excelDataList == null || excelDataList.isEmpty()) {
                return Result.fail("Excel文件中没有有效数据");
            }

            // 转换为实体对象
            List<ExamQuestion> examQuestions = new ArrayList<>();
            for (int i = 0; i < excelDataList.size(); i++) {
                ExamQuestionExcelImport excelData = excelDataList.get(i);
                ExamQuestion examQuestion = convertExcelImportToEntity(excelData, examId, i + 1);
                if (examQuestion != null) {
                    examQuestions.add(examQuestion);
                }
            }

            if (examQuestions.isEmpty()) {
                return Result.fail("没有有效的题目数据");
            }

            // 验证分数
            Result<?> validateResult = validateQuestionScores(examId, examQuestions ,QuestionType);
            if (validateResult.getCode() != 200) {
                return validateResult;
            }

            // 先删除该考试的所有题目
            examQuestionMapper.deleteByExamIdAndQuestionType(examId, (long) QuestionType);

            // 批量插入新题目
            boolean success = batchSave(examQuestions);
            if (success) {
                String message = String.format("Excel导入成功，共导入 %d 道题目", examQuestions.size());
                return Result.success(message);
            } else {
                return Result.fail("Excel导入失败");
            }

        } catch (IOException e) {
            log.error("读取Excel文件失败", e);
            return Result.fail("读取Excel文件失败：" + e.getMessage());
        } catch (Exception e) {
            log.error("Excel导入失败", e);
            return Result.fail("Excel导入失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> importSubjectiveFromExcelFile(Long examId, MultipartFile file) {
        try {
            int QuestionType = QuestionTypeCode.SUBJECTIVE.getCode();
            if (examId == null) {
                return Result.fail("考试ID不能为空");
            }
            if (file == null || file.isEmpty()) {
                return Result.fail("请选择要导入的Excel文件");
            }

            // 检查文件类型
            String fileName = file.getOriginalFilename();
            if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
                return Result.fail("请上传Excel文件（.xlsx或.xls格式）");
            }

            // 配置EasyPoi导入参数
            ImportParams importParams = new ImportParams();
            importParams.setTitleRows(1); // 标题行数
            importParams.setHeadRows(1);  // 表头行数
            importParams.setNeedVerify(false); // 不需要校验

            // 解析Excel文件
            List<ExamQuestionSubjectiveExcelImport> excelDataList;
            try (InputStream inputStream = file.getInputStream()) {
                excelDataList = ExcelImportUtil.importExcel(
                    inputStream, 
                    ExamQuestionSubjectiveExcelImport.class, 
                    importParams
                );
            }

            if (excelDataList == null || excelDataList.isEmpty()) {
                return Result.fail("Excel文件中没有有效数据");
            }

            // 转换为实体对象
            List<ExamQuestion> examQuestions = new ArrayList<>();
            for (int i = 0; i < excelDataList.size(); i++) {
                ExamQuestionSubjectiveExcelImport excelData = excelDataList.get(i);
                ExamQuestion examQuestion = convertSubjectiveExcelImportToEntity(excelData, examId, i + 1);
                if (examQuestion != null) {
                    examQuestions.add(examQuestion);
                }
            }

            if (examQuestions.isEmpty()) {
                return Result.fail("没有有效的题目数据");
            }

            // 验证分数
            Result<?> validateResult = validateQuestionScores(examId, examQuestions,QuestionType);
            if (validateResult.getCode() != 200) {
                return validateResult;
            }

            // 先删除该考试的所有题目
            examQuestionMapper.deleteByExamIdAndQuestionType(examId, (long)QuestionType);

            // 批量插入新题目
            boolean success = batchSave(examQuestions);
            if (success) {
                String message = String.format("主观题Excel导入成功，共导入 %d 道题目", examQuestions.size());
                return Result.success(message);
            } else {
                return Result.fail("主观题Excel导入失败");
            }

        } catch (IOException e) {
            log.error("读取Excel文件失败", e);
            return Result.fail("读取Excel文件失败：" + e.getMessage());
        } catch (Exception e) {
            log.error("主观题Excel导入失败", e);
            return Result.fail("主观题Excel导入失败：" + e.getMessage());
        }
    }

    @Override
    public Result<?> validateQuestionScores(Long examId, List<ExamQuestion> questions, Integer QuestionType) {
        if (questions == null || questions.isEmpty()) {
            return Result.success("验证通过");
        }

        int objectiveTotalScore = 0;
        int subjectiveTotalScore = 0;

        for (ExamQuestion question : questions) {
            if (question.getScore() == null || question.getScore() < 0) {
                return Result.fail("题目分值不能为空或负数");
            }

            if (QuestionTypeCode.OBJECTIVE.getCode() == question.getQuestionType()) {
                objectiveTotalScore += question.getScore();
            } else if (QuestionTypeCode.SUBJECTIVE.getCode() == question.getQuestionType()) {
                subjectiveTotalScore += question.getScore();
            }
        }

        // 检查客观题总分是否等于100
        if (objectiveTotalScore != 100 && QuestionTypeCode.OBJECTIVE.getCode() == QuestionType) {
            return Result.fail("客观题总分必须等于100分，当前总分：" + objectiveTotalScore + "分");
        }

        // 检查主观题总分是否等于100
        if (subjectiveTotalScore != 100 && QuestionTypeCode.SUBJECTIVE.getCode() == QuestionType) {
            return Result.fail("主观题总分必须等于100分，当前总分：" + subjectiveTotalScore + "分");
        }

        return Result.success("验证通过");
    }

    /**
     * 将Excel导入数据转换为实体对象
     */
    private ExamQuestion convertExcelImportToEntity(ExamQuestionExcelImport excelData, Long examId, int sortOrder) {
        try {
            ExamQuestion examQuestion = new ExamQuestion();
            examQuestion.setExamId(examId);
            examQuestion.setQuestionContent(excelData.getQuestionContent());
            examQuestion.setScore(excelData.getScore());
            examQuestion.setCorrectAnswer(excelData.getCorrectAnswer());
            examQuestion.setSortOrder(sortOrder);

            // 解析题目类型
            String questionTypeStr = excelData.getQuestionType() != null ? excelData.getQuestionType().trim() : "";
            if (questionTypeStr.startsWith("1") || questionTypeStr.contains("选择题")) {
                examQuestion.setQuestionType((short) QuestionTypeCode.OBJECTIVE.getCode());
                // 构建选项JSON
                Map<String, String> optionsMap = new HashMap<>();
                if (excelData.getOptionOne() != null && !excelData.getOptionOne().trim().isEmpty()) {
                    optionsMap.put("A", excelData.getOptionOne().trim());
                }
                if (excelData.getOptionTwo() != null && !excelData.getOptionTwo().trim().isEmpty()) {
                    optionsMap.put("B", excelData.getOptionTwo().trim());
                }
                if (excelData.getOptionThree() != null && !excelData.getOptionThree().trim().isEmpty()) {
                    optionsMap.put("C", excelData.getOptionThree().trim());
                }
                if (excelData.getOptionFour() != null && !excelData.getOptionFour().trim().isEmpty()) {
                    optionsMap.put("D", excelData.getOptionFour().trim());
                }
                examQuestion.setOptions(JSON.toJSONString(optionsMap));
            } else if (questionTypeStr.startsWith("2") || questionTypeStr.contains("判断题")) {
                examQuestion.setQuestionType((short) QuestionTypeCode.OBJECTIVE.getCode());
                // 构建判断题选项JSON
                Map<String, String> optionsMap = new HashMap<>();
                optionsMap.put("A", "正确");
                optionsMap.put("B", "错误");
                examQuestion.setOptions(JSON.toJSONString(optionsMap));
            } else {
                log.warn("未知的客观题类型：{}", questionTypeStr);
                return null;
            }

            return examQuestion;
        } catch (Exception e) {
            log.error("转换Excel数据失败", e);
            return null;
        }
    }

    /**
     * 将主观题Excel导入数据转换为实体对象
     */
    private ExamQuestion convertSubjectiveExcelImportToEntity(ExamQuestionSubjectiveExcelImport excelData, Long examId, int sortOrder) {
        try {
            ExamQuestion examQuestion = new ExamQuestion();
            examQuestion.setExamId(examId);
            examQuestion.setQuestionContent(excelData.getQuestionContent());
            examQuestion.setScore(excelData.getScore());
            examQuestion.setSortOrder(sortOrder);
            examQuestion.setQuestionType((short) QuestionTypeCode.SUBJECTIVE.getCode());

            // 构建主观题评分标准JSON
            Map<String, Object> scoringCriteria = new HashMap<>();
            if (excelData.getArtistryScore() != null && !excelData.getArtistryScore().trim().isEmpty()) {
                scoringCriteria.put("艺术性", excelData.getArtistryScore().trim());
            }
            if (excelData.getTechnicalityScore() != null && !excelData.getTechnicalityScore().trim().isEmpty()) {
                scoringCriteria.put("技术性", excelData.getTechnicalityScore().trim());
            }
            if (excelData.getSocialityScore() != null && !excelData.getSocialityScore().trim().isEmpty()) {
                scoringCriteria.put("社会性", excelData.getSocialityScore().trim());
            }
            if (excelData.getInnovationScore() != null && !excelData.getInnovationScore().trim().isEmpty()) {
                scoringCriteria.put("创新性", excelData.getInnovationScore().trim());
            }

            // 将评分标准作为选项存储
            examQuestion.setOptions(JSON.toJSONString(scoringCriteria));
            
            // 主观题没有标准答案，设置为空或评分标准
            examQuestion.setCorrectAnswer("主观题，需人工评分");

            return examQuestion;
        } catch (Exception e) {
            log.error("转换主观题Excel数据失败", e);
            return null;
        }
    }
}
